iT邦幫忙

2021 iThome 鐵人賽

DAY 3
0
自我挑戰組

Leetcode刷題筆記系列 第 3

[Day 3] Leetcode 848. Shifting Letters (C++)

  • 分享至 

  • xImage
  •  

前言

今天的題目在這裡: 848. Shifting Letters,被歸類為medium,乍看之下想說應該是easy頗簡單,結果還是不小心踩了幾個坑QQ 是關於char的數值範圍與int的數值範圍,還是有些知識不足的地方,一起來看看吧!

想法

看到題目,第一眼想說只想遍歷一次的話,就要倒著來了,因為它字串的第一個字母會隨著後面的每次shift都跟著shift;然後肯定是要先記錄一個shift的總和,才知道最後總共要移多少;另外呢,要把int轉成字母/英文字母轉成int是很簡單的,你可以直接打開這個線上編譯器試試看:

// Example program
#include <iostream>
#include <string>
using namespace std;
int main()
{
    int a = 'a', z = 'z';
    cout << "'a' to int: " << a << endl;
    cout << "'z' to int: " << z << endl;
    char ca = 97, cz = 122;
    cout << "97 to char: " << ca << endl;
    cout << "122 to char: " << cz << endl;
}

輸出如下:

'a' to int: 97
'z' to int: 122
97 to char: a
122 to char: z

可以看到它可以動態直接轉型~ 小寫英文字母'a'~'z'的數值範圍在97~122之間。
但這裡有個陷阱,就是你如果給char x = 某數字;,然後某數字<0 或 >255的話,就會overflow!(在unsigned char的情形中)
這是因為char是由1byte來儲存的,容納的數值範圍只有2^8=256,char在不同編譯器中可能是signed charunsigned char,分別可接受的數值範圍是-128~127/ 0~255,可以看這邊
順帶一提,int則是4byte來儲存的,容納的數值範圍是2^32,從-2,147,483,648~2,147,483,647

所以來看看我一開始的寫法XD

class Solution {
public:
    string shiftingLetters(string s, vector<int>& shifts) {
        // iterate from the end, so we can record the nums we need to add for each char
        char tmp;
        int sum=0;
        string ans=s;
        for(int i=s.length()-1;i>=0;--i){
            tmp = s[i];
            sum+= shifts[i];
            tmp+=sum;
            if(tmp>'z'){
                tmp = (tmp-'a')%26+'a';
            }
            ans[i] = tmp;
        }
        return ans;
    }
};

裡面會有兩個爆點XDD

  • 第一個是 tmp+=sum會在tmp+上去>255的時候就錯誤,
  • 第二個是sum+= shifts[i];>2,147,483,647會溢位

數值小的時候沒問題,比較大的test case就壞了
那要怎麼解決呢?就擅用提早%26取餘數來避免最後加總才太大了!
以下是修改後的版本,順便直接拿題目的s直接修改了XD

class Solution {
public:
    string shiftingLetters(string s, vector<int>& shifts) {
        // record the total shift distance
        int sum=0;
        // iterate from the end
        for(int i = shifts.size() - 1; i >= 0; --i) {
            // mod in every round to ensure the range
            sum = (shifts[i] + sum) % 26;
            s[i] = (s[i]-'a'+sum)%26+'a';
        } 
        return s;
    }
};

結語

本來想說題目蠻簡單,沒想到還是可以複習到一些特別的地方~
最近在看C++ Primer這本書,可能可以順便在這邊提一些書中提到的東西。


上一篇
[Day 2] Leetcode 206. Reverse Linked List (C++)
下一篇
[Day 4] Leetcode 764. Largest Plus Sign (C++)
系列文
Leetcode刷題筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言